/*
 * @Author: fisher
 * @Date: 2024-02-26 21:26:15
 * @LastEditors: fisher luthor-li@qq.com
 * @LastEditTime: 2024-03-08 17:12:33
 * @FilePath: \allback\utils\ueconfig.js
 * @Description:
 */
const fs = require('fs-extra')
const path = require('path')
const Cluster = require('../models/clusterModel')
const { post } = require('../utils/request')
// const dayjs = require('dayjs')
exports.copysignalling = async config => {
  async function copyAndConfigureServer(src, dest, configChanges) {
    try {
      // 复制源文件夹到目标文件夹
      await fs.copy(src, dest)
      // 指定配置文件路径
      const configPath = path.join(dest, 'config.json') // 根据您的实际配置文件位置来更改路径
      // 读取 JSON 配置文件内容
      const config = await fs.readJson(configPath)
      // 修改配置文件
      Object.assign(config, configChanges)
      // 写回 JSON 配置文件
      await fs.writeJson(configPath, config, { spaces: 2 })
      return `Server copied and configured: ${dest}`
    } catch (err) {
      // 错误处理
      throw new HttpError(err.message, 400)
    }
  }
  try {
    // const portList = ports.split(',')
    const src = path.resolve(__dirname, '../signalling/template')
    const dest = path.resolve(__dirname, `../signalling/${config.name}`)
    let configChanges = {}
    // 根据useHttps添加对应参数
    if (config.useHttps) {
      configChanges.UseHTTPS = config.useHttps
      configChanges.HttpsPort = parseInt(config.port)
      configChanges.HTTPSCertFile = config.httpsCertFile
      configChanges.HTTPSKeyFile = config.httpsKeyFile
    } else {
      configChanges.HttpPort = parseInt(config.port)
    }
    // 根据是否使用中继添加中继参数
    if (config.useRelay) {
      const options = []
      config.relays.forEach(item => {
        options.push({
          urls: [item.stun, item.turn],
          username: item.relayUsername,
          credential: item.relayPassword
        })
      })
      configChanges.peerConnectionOptions = JSON.stringify({
        offerExtmapAllowMixed: false,
        iceServers: options
      })
    }
    // 继续添加常规参数
    configChanges.StreamerPort =
      parseInt(config.port) + parseInt(process.env.StreamerPortDeviation)
    configChanges.SFUPort =
      parseInt(config.port) + parseInt(process.env.StreamerPortDeviation) * 2
    configChanges.instanceId = config._id
    configChanges.platformPort = process.env.PORT
    configChanges.platformHost = process.env.HOST
    await copyAndConfigureServer(src, dest, configChanges)
  } catch (err) {
    throw new HttpError('请检查参数是否正确!', 400)
  }
}

exports.generateStartconfig = async configs => {
  try {
    // 指定配置文件路径
    const configPath = path.resolve(__dirname, '../signalling.json') // 根据您的实际配置文件位置来更改路径
    let configChanges = {
      apps: []
    }
    // 定义发送给集群节点的请求列表
    const requests = []
    const requestMap = new Map()
    // 获取local nodejs地址
    for (let i = 0, len = configs.length; i < len; i++) {
      // 添加信令服务器配置
      configChanges.apps.push({
        name: `server_${configs[i]._id}`,
        script: 'cirrus.js',
        cwd: path.resolve(__dirname, `../signalling/${configs[i].name}`),
        args: ''
      })
      // 发送ue启动请求，通知集群节点启动
      // 找到集群节点
      const clusterNode = await Cluster.findById(configs[i].clusterId)
      // 设置请求地址
      const url = `${clusterNode.protocol}://${clusterNode.host}:${clusterNode.port}/ueinstance/startUeinstance`
      // 设置请求参数
      const data = {
        PixelStreamingURL: `ws://${configs[i].instanceIp}:${parseInt(configs[i].port) + parseInt(process.env.StreamerPortDeviation)}`,
        instanceId: configs[i]._id,
        path: configs[i].projectPath
      }
      // 当map中已经存在了clusterid，则查询数据，推入数据
      if (requestMap.has(clusterNode._id.toString())) {
        requestMap.get(clusterNode._id.toString()).data.push(data)
      } else {
        // 当map不存在clusterid节点，则新建数据传入
        requestMap.set(clusterNode._id.toString(), {
          url,
          data: [data]
        })
      }
    }
    // 根据requestMap数据整合发送请求给集群节点
    for (let value of requestMap.values()) {
      requests.push(post(value.url, { data: value.data }))
    }
    // 统一发送请求
    await Promise.all(requests)
    // 写回 JSON 配置文件
    await fs.writeJson(configPath, configChanges, { spaces: 2 })
    return configPath
  } catch (err) {
    throw new HttpError(err.message, 400)
  }
}
